package com.example.musicproject_b.Controller;


import com.alibaba.fastjson.JSON;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.common.b_pojo.BAdmin;
import com.example.common.b_pojo.BAdminUser;
import com.example.common.b_pojo.BRole;
import com.example.common.utils.JWTUtils;
import com.example.common.utils.ResultCodeEnum;
import com.example.common.utils.Resultb;
import com.example.service.Imp.UserDetailsServiceImp;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/B_admin")
public class AdminLoginController {


    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private AuthenticationManager authenticationManager;

    /*redis前缀*/
    public static final String USER_PREFIX = "login:";

    /*管理员角色权限*/
    public static final String USERINFO_PREFIX = "adminpermssion:";

    public static final String Admin_ROLE_PREFIX = "admininfo:";

    @Autowired
    private UserService userService;

    @Autowired
    private UserDetailsServiceImp userDetailsServiceImp;

    @RequestMapping("/login")
    public Resultb login(@RequestBody BAdmin admin) {
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                new UsernamePasswordAuthenticationToken(admin.getAdmin(), admin.getPassword());
//        让令牌作为参数传给AuthenticationManager，让AuthenticationManager进行认证（在UserDetailsServiceImp里面验证），认证成功返回一个Authentication对象
        Authentication authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        if (authenticate == null) {
            return new Resultb().setResult(ResultCodeEnum.LOGINERROR);
        } else {
//            查询出来获取用户信息,将用户信息生成token存入redis,然后返回token
//            TODO 在登陆时候查询数据库，获取用户所有信息，封装成authenticate
            BAdminUser bAdminuser = (BAdminUser) authenticate.getPrincipal();
            HashMap<String, String> map = new HashMap<>();
            map.put("id", String.valueOf(bAdminuser.getId()));
            map.put("username", bAdminuser.getAdmin());
            String token = JWTUtils.getToken(map);
//            TODO 多一次查询，冗余，需要优化
            List<BRole> admininfo =userService.AdminInfo(Long.valueOf(bAdminuser.getId()));
            String userinfo = JSON.toJSONString(admininfo);

            stringRedisTemplate.opsForValue().set(Admin_ROLE_PREFIX + bAdminuser.getId(), JSON.toJSONString(bAdminuser), 7, TimeUnit.DAYS);
            stringRedisTemplate.opsForValue().set(USERINFO_PREFIX + bAdminuser.getId(), userinfo, 30, TimeUnit.DAYS);
//            TODO USER_PREFIX = "login:"为redis中创建login文件夹分类，方便管理
            stringRedisTemplate.opsForValue().set(USER_PREFIX + String.valueOf(bAdminuser.getId()), token, 30, TimeUnit.DAYS);
            HashMap<String, String> maptoken = new HashMap<>();
//            TODO 需要修改
            maptoken.put("token", token);
            maptoken.put("username", bAdminuser.getAdmin());
            maptoken.put("phone", bAdminuser.getPhone());
            return new Resultb().success(maptoken);
        }
    }

    @RequestMapping("/register")
    public Resultb register(@RequestBody BAdmin admin) {
        Boolean isregister = userService.registerAdmin(admin.getAdmin(), admin.getPassword(), admin.getPhone());
        if (!isregister) {
            return new Resultb().setResult(ResultCodeEnum.REGISTERERROR);
        }
        return new Resultb().setResult(ResultCodeEnum.REGISTERSUCCESS);
    }

    /**
     * @return
     * @param @param null
     * @author znk
     * @date 2024/10/12 11:01
     * 登陆成功后根据前端传回来的token查询redis中的数据，更具id获取用户角色和菜单，返回给前端
     * 第一次查询出来的信息返回给前端，并存在redis里面，第二次验证token直接在redis里面去就行
     */
    @RequestMapping("/info")
    public Resultb info(HttpServletRequest request) {
//        获取请求头里面的token,获取载荷里面的id
        String token = request.getHeader("token");
        DecodedJWT decodedJWT =JWTUtils.getTokenInfo(token);
        String id =decodedJWT.getClaims().get("id").asString();
//        从redis中获取信息，返回给前端
        if(stringRedisTemplate.opsForValue().get(USERINFO_PREFIX + id) == null ){
            List<BRole> admininfo =userService.AdminInfo(Long.valueOf(id));
            String userinfo = JSON.toJSONString(admininfo);
            stringRedisTemplate.opsForValue().set(USERINFO_PREFIX + id, userinfo, 30, TimeUnit.MINUTES);
            return new Resultb().success(admininfo);
        }else {
            String userinfo = stringRedisTemplate.opsForValue().get(USERINFO_PREFIX + id);
            List<BRole> admininfo = JSON.parseArray(userinfo, BRole.class);
            return new Resultb().success(admininfo);
        }
    }

}
